/*
 * #%L
 * BroadleafCommerce Admin Module
 * %%
 * Copyright (C) 2009 - 2013 Broadleaf Commerce
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package com.fsquare.controller.entity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.broadleafcommerce.admin.server.service.handler.ProductCustomPersistenceHandler;
import org.broadleafcommerce.admin.web.controller.entity.AdminProductController;
import org.broadleafcommerce.common.i18n.domain.Translation;
import org.broadleafcommerce.common.locale.domain.Locale;
import org.broadleafcommerce.core.catalog.domain.Product;
import org.broadleafcommerce.core.catalog.service.CatalogService;
import org.broadleafcommerce.openadmin.dto.ClassMetadata;
import org.broadleafcommerce.openadmin.dto.DynamicResultSet;
import org.broadleafcommerce.openadmin.dto.Entity;
import org.broadleafcommerce.openadmin.dto.Property;
import org.broadleafcommerce.openadmin.dto.SectionCrumb;
import org.broadleafcommerce.openadmin.server.dao.DynamicEntityDao;
import org.broadleafcommerce.openadmin.server.domain.PersistencePackageRequest;
import org.broadleafcommerce.openadmin.web.form.component.ListGrid;
import org.broadleafcommerce.openadmin.web.form.component.ListGridRecord;
import org.broadleafcommerce.openadmin.web.form.entity.EntityForm;
import org.broadleafcommerce.openadmin.web.form.entity.Field;
import org.broadleafcommerce.openadmin.web.form.entity.FieldGroup;
import org.broadleafcommerce.openadmin.web.form.entity.Tab;
import org.broadleafcommerce.openadmin.web.service.FormBuilderService;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fsquare.admin.service.ExtFormBuilderService;
import com.fsquare.admin.service.handler.SkuMovementCustomPersistenceHandler;
import com.fsquare.inventory.domain.SkuInventory;
import com.fsquare.inventory.domain.SkuMovement;
import com.fsquare.inventory.domain.SkuMovementImpl;
import com.fsquare.inventory.service.InventoryService;
import com.fsquare.inventory.service.InventoryUnavailableException;

/**
 * Handles admin operations for the {@link Product} entity. Editing a product requires custom criteria in order to properly
 * invoke the {@link ProductCustomPersistenceHandler}
 * 
 * @author Andre Azzolini (apazzolini)
 * @see {@link ProductCustomPersistenceHandler}
 */
//@Controller("blAdminProductController")
@RequestMapping("/" + ExtAdminProductController.SECTION_KEY)
public class ExtAdminProductController extends AdminProductController {
    
    protected static final String SECTION_KEY = "product";
    
    @Resource(name = "fsquareInventoryService")
	protected InventoryService inventoryService;
    
    @Resource(name = "blCatalogService")
	protected CatalogService catalogService;
    
//    @Resource(name="blDynamicEntityDao")
//    protected DynamicEntityDao dynamicEntityDao;
    
    @Resource(name = "fsquareSkuMovementCustomPersistenceHandler")
    protected SkuMovementCustomPersistenceHandler skuMovementCustomPersistenceHandler;
    
    @Resource(name = "fsquareFormBuilderService")
    protected ExtFormBuilderService extformService;
    
    @Override
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String viewEntityForm(HttpServletRequest request, HttpServletResponse response, Model model,
            @PathVariable Map<String, String> pathVars,
            @PathVariable(value = "id") String id) throws Exception {
        String view = super.viewEntityForm(request, response, model, pathVars, id);
        
//        //Skus have a specific toolbar action to generate Skus based on permutations
        EntityForm entityForm = (EntityForm) model.asMap().get("entityForm");
        Set<Tab> tabs = entityForm.getTabs();
        
        Product product = catalogService.findProductById(Long.parseLong(id));
        
        List<SkuMovement> skuMovements = inventoryService.getSkuMovements(product.getDefaultSku().getId());
        SkuInventory skuInventory = inventoryService.getInventory(product.getDefaultSku().getId());
        
        for(Tab tab: tabs) {
        	if("ProductImpl_Inventory_Tab".equals(tab.getTitle())) {

        		Set<Field> inventoryFields = skuInventory.getHeaderFields();
        		Map<String, Object> inventoryFieldsMap =  skuInventory.getEntityMap();
        		for (Field field : inventoryFields) {
					Field newField = field;
					if(!field.getFieldType().equals("")) {
						Object object = inventoryFieldsMap.get(field.getName());
						if(object != null) {
							newField.withDisplayValue(object.toString());
						} 
						if(newField.getName().equals("quantityAvailable")) {
							newField.setFieldType("inventory_update");
							newField.setReadOnly(false);
							newField.setForeignKeyDisplayValueProperty(id.toString());
						}
							
//						newField.setReadOnly(true);
					}
					FieldGroup fg = tab.getFieldGroups().iterator().next();
					fg.addField(newField);

				}
        		
        		
        		SkuMovement skuMov = new SkuMovementImpl();	
                final Set<Field> fields = skuMov.getHeaderFields();
        		ListGrid listGrid = new ListGrid();
        		listGrid.setClassName(SkuMovementImpl.class.getName());
        		listGrid.getHeaderFields().addAll(fields);
        		listGrid.setListGridType(ListGrid.Type.ADORNED);
        		listGrid.setSectionKey(entityForm.getSectionKey());
	            listGrid.setOrder(2000);
	            listGrid.setIdProperty("id");
	            listGrid.setStartIndex(0);
	            listGrid.setTotalRecords(skuMovements.size());
	            listGrid.setPageSize(50);
	            listGrid.setFriendlyName("SkuMovements");
	            listGrid.setCanFilterAndSort(false);

        		for (SkuMovement skuMovement : skuMovements) {
        			Map<String, Object> map =  skuMovement.getEntityMap();        			
                    ListGridRecord record = new ListGridRecord();
                    record.setListGrid(listGrid);
                    record.setId(String.valueOf(skuMovement.getId()));
                    for (Field field : fields) {
						Field newField = field;
						if(!field.getFieldType().equals("")) {
							
							Object object = map.get(field.getName());
							
							if(object != null) {
								newField.withDisplayValue(object.toString()).setValue(object.toString());
								record.getFields().add(newField);
							} 
						}
						
					}
//                    for(Field field : record.getFields()) {
//						System.out.println("field.getName: "+field.getName()+"= "+field.getDisplayValue());
//
//                    }
//                    System.err.println("XXX");
                    listGrid.getRecords().add(record);

                }
        		//
        		tab.getListGrids().add(listGrid);
        	}
        }

        return view;
    }
    
    @RequestMapping(value = "/updateInventory", produces = "application/json")
    @ResponseBody
    public Map<String, Object> updateInventory(HttpServletRequest request, HttpServletResponse response){
    	Map<String, Object> result = new HashMap<String, Object>();
    	String id = request.getParameter("productId");
    	String quantity = request.getParameter("quantity");
    	String inventoryAction = request.getParameter("inventoryAction");
    	List<String> errors = new ArrayList<String>();
    	if(id == null || id.equals("")){
    		errors.add("Invalid id");
    		result.put("errors", errors);
    		return result;
    	}
    	Product product = catalogService.findProductById(Long.parseLong(id));
        if(product == null){
        	errors.add("Product not found");
    		result.put("errors", errors);
    		return result;
        }
        
    	try {
    		SkuInventory newSkuInventory = null;
    		if(inventoryAction.equals("remove"))
    			newSkuInventory = inventoryService.decrementInventory(product.getDefaultSku().getId(), Integer.parseInt(quantity));
    		if(inventoryAction.equals("add"))
    			newSkuInventory = inventoryService.incrementInventory(product.getDefaultSku().getId(), Integer.parseInt(quantity));
    		if(newSkuInventory == null)
    			result.put("quantity", 0);
    		else
    			result.put("quantity", newSkuInventory.getQuantityAvailable());
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (InventoryUnavailableException e) {
			e.printStackTrace();
		}
    	
    	return result;
    }
    
    
    
}
